/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package res.flags;

/*
 * Copyright (C) 2012 Neo Visionaries Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import java.util.HashMap;
import java.util.Map;


/**
 * ISO_3166-1ISO 3166-1
 * country code.
 *
 * <p>
 * Enum names of this enum themselves are represented by
 * ISO_3166-1_alpha-2ISO 3166-1 alpha-2
 * codes. There are instance methods to get the country name ({@link #getName()}), the
 * ISO_3166-1_alpha-3" >ISO 3166-1 alpha-3
 * code ({@link #getAlpha3()}) and the
 * ISO_3166-1_numericISO 3166-1 numeric
 * code ({@link #getNumeric()}).
 * In addition, there are static methods to get a CountryCode instance that
 * corresponds to a given alpha-2/alpha-3/numeric code ({@link #getByCode(String)},
 * {@link #getByCode(int)}).
 * </p>
 *
 * <pre style="background-color: #EEEEEE; margin-left: 2em; margin-right: 2em; border: 1px solid black;
 * <span style="color: darkgreen;// EXAMPLE</span>
 *
 * CountryCode cc = CountryCode.{@link #getByCode(String) getByCode}("JP");
 *
 * <span style="color: darkgreen;// Country name</span>
 * System.out.println("Country name = " + cc.{@link #getName()});                  <span style="color: darkgreen;// "Japan"</span>
 *
 * <span style="color: darkgreen;// ISO 3166-1 alpha-2 code</span>
 * System.out.println("ISO 3166-1 alpha-2 code = " + cc.{@link #getAlpha2()});     <span style="color: darkgreen;// "JP"</span>
 *
 * <span style="color: darkgreen;// ISO 3166-1 alpha-3 code</span>
 * System.out.println("ISO 3166-1 alpha-3 code = " + cc.{@link #getAlpha3()});     <span style="color: darkgreen;// "JPN"</span>
 *
 * <span style="color: darkgreen;// ISO 3166-1 numeric code</span>
 * System.out.println("ISO 3166-1 numeric code = " + cc.{@link #getNumeric()});    <span style="color: darkgreen;// 392</span>
 * </pre>
 *
 * @author Takahiko Kawasaki
 */
public enum CountryCode
{
    // @formatter:off
    /** AndorraAndorra */
    AD("Andorra", "AND", 16),

    /** United_Arab_EmiratesUnited Arab Emirates */
    AE("United Arab Emirates", "ARE", 784),

    /** AfghanistanAfghanistan */
    AF("Afghanistan", "AFG", 4),

    /** Antigua_and_BarbudaAntigua and Barbuda */
    AG("Antigua and Barbuda", "ATG", 28),

    /** AnguillaAnguilla */
    AI("Anguilla", "AIA", 660),

    /** AlbaniaAlbania */
    AL("Albania", "ALB", 8),

    /** ArmeniaArmenia */
    AM("Armenia", "ARM", 51),

    /** Netherlands_AntillesNetherlands Antilles */
    AN("Netherlands Antilles", "ANT", 530),

    /** AngolaAngola */
    AO("Angola", "AGO", 24),

    /** AntarcticaAntarctica */
    AQ("Antarctica", "ATA", 10),

    /** ArgentinaArgentina */
    AR("Argentina", "ARG", 32),

    /** American_SamoaAmerican Samoa */
    AS("American Samoa", "ASM", 16),

    /** AustriaAustria */
    AT("Austria", "AUT", 40),

    /** AustraliaAustralia */
    AU("Australia", "AUS", 36),

    /** ArubaAruba */
    AW("Aruba", "ABW", 533),

    /** %C3%85land_Islands&Aring;land Islands */
    AX("\u212Bland Islands", "ALA", 248),

    /** AzerbaijanAzerbaijan */
    AZ("Azerbaijan", "AZE", 31),

    /** Bosnia_and_HerzegovinaBosnia and Herzegovina */
    BA("Bosnia and Herzegovina", "BIH", 70),

    /** BarbadosBarbados */
    BB("Barbados", "BRB", 52),

    /** BangladeshBangladesh */
    BD("Bangladesh", "BGD", 50),

    /** BelgiumBelgium */
    BE("Belgium", "BEL", 56),

    /** Burkina_FasoBurkina Faso */
    BF("Burkina Faso", "BFA", 854),

    /** BulgariaBulgaria */
    BG("Bulgaria", "BGR", 100),

    /** BahrainBahrain */
    BH("Bahrain", "BHR", 48),

    /** BurundiBurundi */
    BI("Burundi", "BDI", 108),

    /** BeninBenin */
    BJ("Benin", "BEN", 204),

    /** Saint_Barth%C3%A9lemySaint Barth&eacute;lemy */
    BL("Saint Barth\u00E9lemy", "BLM", 652),

    /** BermudaBermuda */
    BM("Bermuda", "BMU", 60),

    /** BruneiBrunei Darussalam */
    BN("Brunei Darussalam", "BRN", 96),

    /** BoliviaPlurinational State of Bolivia */
    BO("Plurinational State of Bolivia", "BOL", 68),

    /** Caribbean_NetherlandsBonaire, Sint Eustatius and Saba */
    BQ("Bonaire, Sint Eustatius and Saba", "BES", 535),

    /** BrazilBrazil */
    BR("Brazil", "BRA", 76),

    /** The_BahamasBahamas */
    BS("Bahamas", "BHS", 44),

    /** BhutanBhutan */
    BT("Bhutan", "BTN", 64),

    /** Bouvet_IslandBouvet Island */
    BV("Bouvet Island", "BVT", 74),

    /** BotswanaBotswana */
    BW("Botswana", "BWA", 72),

    /** BelarusBelarus */
    BY("Belarus", "BLR", 112),

    /** BelizeBelize */
    BZ("Belize", "BLZ", 84),

    /** CanadaCanada */
    CA("Canada", "CAN", 124),

    /** Cocos_(Keeling)_IslandsCocos (Keeling) Islands */
    CC("Cocos Islands", "CCK", 166),

    /** Democratic_Republic_of_the_CongoThe Democratic Republic of the Congo */
    CD("The Democratic Republic of the Congo", "COD", 180),

    /** Central_African_RepublicCentral African Republic */
    CF("Central African Republic", "CAF", 140),

    /** Republic_of_the_CongoCongo */
    CG("Congo", "COG", 178),

    /** SwitzerlandSwitzerland */
    CH("Switzerland", "CHE", 756),

    /** C%C3%B4te_d%27IvoireC&ocirc;te d'Ivoire */
    CI("C\u00F4te d'Ivoire", "CIV", 384),

    /** Cook_IslandsCook Islands */
    CK("Cook Islands", "COK", 184),

    /** ChileChile */
    CL("Chile", "CHL", 152),

    /** CameroonCameroon */
    CM("Cameroon", "CMR", 120),

    /** ChinaChina */
    CN("China", "CHN", 156),

    /** ColombiaColombia */
    CO("Colombia", "COL", 170),

    /** Costa_RicaCosta Rica */
    CR("Costa Rica", "CRI", 188),

    /** CubaCuba */
    CU("Cuba", "CUB", 192),

    /** Cape_VerdeCape Verde */
    CV("Cape Verde", "CPV", 132),

    /** Cura%C3%A7aoCura&ccedil;ao */
    CW("Cura/u00E7ao", "CUW", 531),

    /** Christmas_IslandChristmas Island */
    CX("Christmas Island", "CXR", 162),

    /** CyprusCyprus */
    CY("Cyprus", "CYP", 196),

    /** Czech_RepublicCzech Republic */
    CZ("Czech Republic", "CZE", 203),

    /** GermanyGermany */
    DE("Germany", "DEU", 276),

    /** DjiboutiDjibouti  */
    DJ("Djibouti", "DJI", 262),

    /** DenmarkDenmark */
    DK("Denmark", "DNK", 208),

    /** DominicaDominica */
    DM("Dominica", "DMA", 212),

    /** Dominican_RepublicDominican Republic */
    DO("Dominican Republic", "DOM", 214),

    /** AlgeriaAlgeria */
    DZ("Algeria", "DZA", 12),

    /** EcuadorEcuador */
    EC("Ecuador", "ECU", 218),

    /** EstoniaEstonia */
    EE("Estonia", "EST", 233),

    /** EgyptEgypt */
    EG("Egypt", "EGY", 818),

    /** Western_SaharaWestern Sahara */
    EH("Western Sahara", "ESH", 732),

    /** EritreaEritrea */
    ER("Eritrea", "ERI", 232),

    /** SpainSpain */
    ES("Spain", "ESP", 724),

    /** EthiopiaEthiopia */
    ET("Ethiopia", "ETH", 231),

    /** FinlandFinland */
    FI("Finland", "FIN", 246),

    /** FijiFiji */
    FJ("Fiji", "FJI", 242),

    /** Falkland_IslandsFalkland Islands (Malvinas) */
    FK("Falkland Islands", "FLK", 238),

    /** Federated_States_of_MicronesiaFederated States of Micronesia */
    FM("Federated States of Micronesia", "FSM", 583),

    /** Faroe_IslandsFaroe Islands */
    FO("Faroe Islands", "FRO", 234),

    /** FranceFrance */
    FR("France", "FRA", 250),

    /** GabonGabon  */
    GA("Gabon", "GAB", 266),

    /** United_KingdomUnited Kingdom */
    GB("United Kingdom", "GBR", 826),

    /** GrenadaGrenada */
    GD("Grenada", "GRD", 308),

    /** Georgia_(country)Georgia */
    GE("Georgia", "GEO", 268),

    /** French_GuianaFrench Guiana */
    GF("French Guiana", "GUF", 254),

    /** GuernseyGuemsey */
    GG("Guemsey", "GGY", 831),

    /** GhanaGhana */
    GH("Ghana", "GHA", 288),

    /** GibraltarGibraltar */
    GI("Gibraltar", "GIB", 292),

    /** GreenlandGreenland */
    GL("Greenland", "GRL", 304),

    /** The_GambiaGambia */
    GM("Gambia", "GMB", 270),

    /** GuineaGuinea */
    GN("Guinea", "GIN", 324),

    /** GuadeloupeGuadeloupe */
    GP("Guadeloupe", "GLP", 312),

    /** Equatorial_GuineaEquatorial Guinea */
    GQ("Equatorial Guinea", "GNQ", 226),

    /** GreeceGreece */
    GR("Greece", "GRC", 300),

    /** South_Georgia_and_the_South_Sandwich_IslandsSouth Georgia and the South Sandwich Islands */
    GS("South Georgia and the South Sandwich Islands", "SGS", 239),

    /** GuatemalaGuatemala */
    GT("Guatemala", "GTM", 320),

    /** GuamGuam */
    GU("Guam", "GUM", 316),

    /** Guinea-BissauGuinea-Bissau */
    GW("Guinea-Bissau", "GNB", 624),

    /** GuyanaGuyana */
    GY("Guyana", "GUY", 328),

    /** Hong_KongHong Kong */
    HK("Hong Kong", "HKG", 344),

    /** Heard_Island_and_McDonald_IslandsHeard Island and McDonald Islands */
    HM("Heard Island and McDonald Islands", "HMD", 334),

    /** HondurasHonduras */
    HN("Honduras", "HND", 340),

    /** CroatiaCroatia */
    HR("Croatia", "HRV", 191),

    /** HaitiHaiti */
    HT("Haiti", "HTI", 332),

    /** HungaryHungary */
    HU("Hungary", "HUN", 348),

    /** IndonesiaIndonesia */
    ID("Indonesia", "IDN", 360),

    /** Republic_of_IrelandIreland */
    IE("Ireland", "IRL", 372),

    /** IsraelIsrael */
    IL("Israel", "ISR", 376),

    /** Isle_of_ManIsle of Man */
    IM("Isle of Man", "IMN", 833),

    /** IndiaIndia */
    IN("India", "IND", 356),

    /** British_Indian_Ocean_TerritoryBritish Indian Ocean Territory */
    IO("British Indian Ocean Territory", "IOT", 86),

    /** IraqIraq */
    IQ("Iraq", "IRQ", 368),

    /** IranIslamic Republic of Iran */
    IR("Islamic Republic of Iran", "IRN", 364),

    /** IcelandIceland */
    IS("Iceland", "ISL", 352),

    /** ItalyItaly */
    IT("Italy", "ITA", 380),

    /** JerseyJersey */
    JE("Jersey", "JEY", 832),

    /** JamaicaJamaica */
    JM("Jamaica", "JAM", 388),

    /** JordanJordan */
    JO("Jordan", "JOR", 400),

    /** JapanJapan */
    JP("Japan", "JPN", 392),

    /** KenyaKenya */
    KE("Kenya", "KEN", 404),

    /** KyrgyzstanKyrgyzstan */
    KG("Kyrgyzstan", "KGZ", 417),

    /** CambodiaCambodia */
    KH("Cambodia", "KHM", 116),

    /** KiribatiKiribati */
    KI("Kiribati", "KIR", 296),

    /** ComorosComoros */
    KM("Comoros", "COM", 174),

    /** Saint_Kitts_and_NevisSaint Kitts and Nevis */
    KN("Saint Kitts and Nevis", "KNA", 659),

    /** North_KoreaDemocratic People's Republic of Korea */
    KP("Democratic People's Republic of Korea", "PRK", 408),

    /** South_KoreaRepublic of Korea */
    KR("Republic of Korea", "KOR", 410),

    /** KuwaitKuwait */
    KW("Kuwait", "KWT", 414),

    /** Cayman_IslandsCayman Islands */
    KY("Cayman Islands", "CYM", 136),

    /** KazakhstanKazakhstan */
    KZ("Kazakhstan", "KAZ", 398),

    /** LaosLao People's Democratic Republic */
    LA("Lao People's Democratic Republic", "LAO", 418),

    /** LebanonLebanon */
    LB("Lebanon", "LBN", 422),

    /** Saint_LuciaSaint Lucia */
    LC("Saint Lucia", "LCA", 662),

    /** LiechtensteinLiechtenstein */
    LI("Liechtenstein", "LIE", 438),

    /** Sri_LankaSri Lanka */
    LK("Sri Lanka", "LKA", 144),

    /** LiberiaLiberia */
    LR("Liberia", "LBR", 430),

    /** LesothoLesotho */
    LS("Lesotho", "LSO", 426),

    /** LithuaniaLithuania */
    LT("Lithuania", "LTU", 440),

    /** LuxembourgLuxembourg */
    LU("Luxembourg", "LUX", 442),

    /** LatviaLatvia */
    LV("Latvia", "LVA", 428),

    /** LibyaLibya */
    LY("Libya", "LBY", 434),

    /** MoroccoMorocco */
    MA("Morocco", "MAR", 504),

    /** MonacoMonaco */
    MC("Monaco", "MCO", 492),

    /** MoldovaRepublic of Moldova */
    MD("Republic of Moldova", "MDA", 498),

    /** MontenegroMontenegro */
    ME("Montenegro", "MNE", 499),

    /** Collectivity_of_Saint_MartinSaint Martin (French part) */
    MF("Saint Martin", "MAF", 663),

    /** MadagascarMadagascar */
    MG("Madagascar", "MDG",450),

    /** Marshall_IslandsMarshall Islands */
    MH("Marshall Islands", "MHL", 584),

    /** Republic_of_MacedoniaThe former Yugoslav Republic of Macedonia */
    MK("The former Yugoslav Republic of Macedonia", "MKD", 807),

    /** MaliMali */
    ML("Mali", "MLI", 466),

    /** MyanmarMyanmar */
    MM("Myanmar", "MMR", 104),

    /** MongoliaMongolia */
    MN("Mongolia", "MNG", 496),

    /** MacauMacao */
    MO("Macao", "MCO", 492),

    /** Northern_Mariana_IslandsNorthern Mariana Islands */
    MP("Northern Mariana Islands", "MNP",580),

    /** MartiniqueMartinique */
    MQ("Martinique", "MTQ", 474),

    /** MauritaniaMauritania */
    MR("Mauritania", "MRT", 478),

    /** MontserratMontserrat */
    MS("Montserrat", "MSR", 500),

    /** MaltaMalta */
    MT("Malta", "MLT", 470),

    /** MauritiusMauritius */
    MU("Mauritius", "MUS", 480),

    /** MaldivesMaldives */
    MV("Maldives", "MDV", 462),

    /** MalawiMalawi */
    MW("Malawi", "MWI", 454),

    /** MexicoMexico */
    MX("Mexico", "MEX", 484),

    /** MalaysiaMalaysia */
    MY("Malaysia", "MYS", 458),

    /** MozambiqueMozambique */
    MZ("Mozambique", "MOZ", 508),

    /** NamibiaNamibia */
    NA("Namibia", "NAM", 516),

    /** New_CaledoniaNew Caledonia */
    NC("New Caledonia", "NCL", 540),

    /** NigerNiger */
    NE("Niger", "NER", 562),

    /** Norfolk_IslandNorfolk Island */
    NF("Norfolk Island", "NFK", 574),

    /** NigeriaNigeria */
    NG("Nigeria","NGA", 566),

    /** NicaraguaNicaragua */
    NI("Nicaragua", "NIC", 558),

    /** NetherlandsNetherlands */
    NL("Netherlands", "NLD", 528),

    /** NorwayNorway */
    NO("Norway", "NOR", 578),

    /** NepalNepal */
    NP("Nepal", "NPL", 524),

    /** NauruNauru */
    NR("Nauru", "NRU", 520),

    /** NiueNiue */
    NU("Niue", "NIU", 570),

    /** New_ZealandNew Zealand */
    NZ("New Zealand", "NZL", 554),

    /** <a href=http://en.wikipedia.org/wiki/Oman"Oman */
    OM("Oman", "OMN", 512),

    /** PanamaPanama */
    PA("Panama", "PAN", 591),

    /** PeruPeru */
    PE("Peru", "PER", 604),

    /** French_PolynesiaFrench Polynesia */
    PF("French Polynesia", "PYF", 258),

    /** Papua_New_GuineaPapua New Guinea */
    PG("Papua New Guinea", "PNG", 598),

    /** PhilippinesPhilippines */
    PH("Philippines", "PHL", 608),

    /** PakistanPakistan */
    PK("Pakistan", "PAK", 586),

    /** PolandPoland */
    PL("Poland", "POL", 616),

    /** Saint_Pierre_and_MiquelonSaint Pierre and Miquelon */
    PM("Saint Pierre and Miquelon", "SPM", 666),

    /** Pitcairn_IslandsPitcairn */
    PN("Pitcairn", "PCN", 612),

    /** Puerto_RicoPuerto Rico */
    PR("Puerto Rico", "PRI", 630),

    /** Palestinian_territoriesOccupied Palestinian Territory */
    PS("Occupied Palestinian Territory", "PSE", 275),

    /** PortugalPortugal */
    PT("Portugal", "PRT", 620),

    /** PalauPalau */
    PW("Palau", "PLW", 585),

    /** ParaguayParaguay */
    PY("Paraguay", "PRY", 600),

    /** QatarQatar */
    QA("Qatar", "QAT", 634),

    /** R%C3%A9unionR&eacute;union */
    RE("R\u00E9union", "REU", 638),

    /** RomaniaRomania */
    RO("Romania", "ROU", 642),

    RS("Serbia", "SRB", 688),

    RU("Russian Federation", "RUS", 643),

    RW("Rwanda", "RWA", 646),

    SA("Saudi Arabia", "SAU", 682),

    SB("Solomon Islands", "SLB", 90),

    SC("Seychelles", "SYC", 690),

    SD("Sudan", "SDN", 729),

    SE("Sweden", "SWE", 752),

    SG("Singapore", "SGP", 702),

    SH("Saint Helena, Ascension and Tristan da Cunha", "SHN", 654),

    SI("Slovenia", "SVN", 705),

    SJ("Svalbard and Jan Mayen", "SJM", 744),

    SK("Slovakia", "SVK", 703),

    SL("Sierra Leone", "SLE", 694),

    SM("San Marino", "SMR", 674),

    SN("Senegal", "SEN", 686),

    SO("Somalia", "SOM", 706),

    SR("Suriname", "SUR", 740),

    SS("South Sudan", "SSD", 728),

    ST("Sao Tome and Principe", "STP", 678),

    SV("El Salvador", "SLV", 222),

    SX("Sint Maarten", "SXM", 534),

    SY("Syrian Arab Republic", "SYR", 760),

    SZ("Swaziland", "SWZ", 748),

    TC("Turks and Caicos Islands", "TCA", 796),

    TD("Chad", "TCD", 148),

    TF("French Southern Territories", "ATF", 260),

    TG("Togo", "TGO", 768),

    TH("Thailand", "THA", 764),

    TJ("Tajikistan", "TJK", 762),

    TK("Tokelau", "TKL", 772),

    TL("Timor-Leste", "TLS", 626),

    TM("Turkmenistan", "TKM", 795),

    TN("Tunisia", "TUN", 788),

    TO("Tonga", "TON", 776),

    TR("Turkey", "TUR", 792),

    TT("Trinidad and Tobago", "TTO", 780),

    TV("Tuvalu", "TUV", 798),

    TW("Taiwan, Province of China", "TWN", 158),

    TZ("United Republic of Tanzania", "TZA", 834),

    UA("Ukraine", "UKR", 804),

    UG("Uganda", "UGA", 800),

    UM("United States Minor Outlying Islands", "UMI", 581),

    US("United States", "USA", 840),

    UY("Uruguay", "URY", 858),

    UZ("Uzbekistan", "UZB", 860),

    VA("Holy See", "VAT", 336),

    VC("Saint Vincent and the Grenadines", "VCT", 670),

    VE("Bolivarian Republic of Venezuela", "VEN", 862),

    VG("British Virgin Islands", "VGB", 92),

    VI("Virgin Islands, U.S.", "VIR", 850),

    VN("Viet Nam", "VNM", 704),

    VU("Vanuatu", "VUT", 548),

    WF("Wallis and Futuna", "WLF", 876),

    WS("Samoa", "WSM", 882),

    YE("Yemen", "YEM", 887),

    YT("Mayotte", "MYT", 175),

    ZA("South Africa", "ZAF", 710),

    ZM("Zambia", "ZMB", 894),

    ZW("Zimbabwe", "ZWE", 716),
    ;
    // @formatter:on


    private static final Map<String, CountryCode> alpha3Map = new HashMap<String, CountryCode>();
    private static final Map<Integer, CountryCode> numericMap = new HashMap<Integer, CountryCode>();


    static
    {
        for (CountryCode cc : values())
        {
            alpha3Map.put(cc.getAlpha3(), cc);
            numericMap.put(cc.getNumeric(), cc);
        }
    }


    private final String name;
    private final String alpha3;
    private final int numeric;


    private CountryCode(String name, String alpha3, int numeric)
    {
        this.name = name;
        this.alpha3 = alpha3;
        this.numeric = numeric;
    }


    public String getName()
    {
        return name;
    }

    public String getAlpha2()
    {
        return name();
    }


    public String getAlpha3()
    {
        return alpha3;
    }

    public int getNumeric()
    {
        return numeric;
    }


    public static CountryCode getByCode(String code)
    {
        if (code == null)
        {
            return null;
        }

        switch (code.length())
        {
            case 2:
                return getByAlpha2Code(code);

            case 3:
                return getByAlpha3Code(code);

            default:
                return null;
        }
    }


    private static CountryCode getByAlpha2Code(String code)
    {
        try
        {
            return Enum.valueOf(CountryCode.class, code);
        }
        catch (IllegalArgumentException e)
        {
            return null;
        }
    }


    private static CountryCode getByAlpha3Code(String code)
    {
        return alpha3Map.get(code);
    }


    public static CountryCode getByCode(int code)
    {
        return numericMap.get(code);
    }
}